package com.geovis.emergency.spd.controller.system;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.geovis.common.core.api.Result;
import com.geovis.common.core.controller.BaseController;
import com.geovis.emergency.spd.biz.filing.service.IFilingSystemDeptService;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillService;
import com.geovis.emergency.spd.biz.pc.service.IPcPlanService;
import com.geovis.emergency.spd.biz.system.service.ISystemDeptService;
import com.geovis.emergency.spd.biz.system.wrapper.ForestNodeMerger;
import com.geovis.emergency.spd.entity.filing.entity.FilingSystemDept;
import com.geovis.emergency.spd.entity.pc.pojo.enums.StatusEnum;
import com.geovis.emergency.spd.entity.system.entity.SystemDept;
import com.geovis.emergency.spd.entity.system.entity.SystemUser;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemDeptQueryDTO;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemDeptSaveDTO;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemDeptUpdateDTO;
import com.geovis.emergency.spd.entity.system.pojo.vo.SystemDeptTreeVO;
import com.geovis.emergency.spd.redis.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 机构表 前端控制器
 * </p>
 *
 * @author hhj
 * @since 2021-01-18
 */
@RestController
@RequestMapping("/system/systemDept")
@RequiredArgsConstructor
@Api(value = "系统管理模块-机构信息相关接口", tags = "系统管理模块-机构信息相关接口")
@Slf4j
@Validated
public class SystemDeptController extends BaseController<ISystemDeptService> {

    private final IPcDrillService pcDrillService;
    private final IPcPlanService pcPlanService;
    private final IFilingSystemDeptService filingSystemDeptService;

    @ApiOperation(value = "保存机构信息", notes = "保存机构信息")
    @PostMapping({"/save"})
    public Result save(@Validated @RequestBody SystemDeptSaveDTO saveDTO) {
        // 1、检查名称是否已存在
        Long deptName = baseService.count(Wrappers.lambdaQuery(SystemDept.class).eq(SystemDept::getDeptName, saveDTO.getDeptName()));
        Assert.isTrue(deptName < 1,"部门名【{}】已被使用！", saveDTO.getDeptName());


        //清除缓存
        baseService.deleteTreeCache();
        SystemDept systemDept = BeanUtil.toBean(saveDTO, SystemDept.class);
        baseService.save(systemDept);
        //保存预案备案的部门
        filingSystemDeptService.saveFromSpd(systemDept);
        return Result.ok();
    }

    @ApiOperation(value = "修改机构信息", notes = "修改资源信息")
    @PostMapping({"/update"})
    public Result update(@Validated @RequestBody SystemDeptUpdateDTO updateDTO) {
        SystemDept old=baseService.getById(updateDTO.getId());
        //如果修改了名称，则判断是否已存在
        if(!old.getDeptName().equals(updateDTO.getDeptName()))
        {
            // 1、检查名称是否已存在
            Long deptName = baseService.count(Wrappers.lambdaQuery(SystemDept.class).eq(SystemDept::getDeptName, updateDTO.getDeptName()));
            Assert.isTrue(deptName < 1,"部门名【{}】已被使用！", updateDTO.getDeptName());
        }


        SystemDept systemDept = BeanUtil.toBean(updateDTO, SystemDept.class);
        baseService.updateById(systemDept);
        //更新预案备案的部门
        filingSystemDeptService.updateFromSpd(systemDept,old.getDeptName());
        return Result.ok();
    }

    /**
     * 返回机构树，注意，改造后，接收的参数不再使用
     * @param queryDTO
     * @return
     */
    @ApiOperation(value = "查询所有机构数据", notes = "查询所有机构数据")
    @PostMapping("/list")
    public Result<List<SystemDeptTreeVO>> list(@Validated @RequestBody SystemDeptQueryDTO queryDTO) {
        List<SystemDeptTreeVO> systemDeptTreeVOS = baseService.deptTree();
        return Result.ok(systemDeptTreeVOS);
    }

    @ApiOperation(value = "批量删除机构数据", notes = "批量删除机构数据")
    @ApiImplicitParams({@ApiImplicitParam(name = "idList", value = "删除id的list", required = true, dataType = "java.util.Set", paramType = "body")})
    @PostMapping("/removeByIdList")
    public Result removeByIdList(@NotNull(message = "删除的id集合不能为空") @RequestBody Set<String> idList) {
        List<String> checkUserIds=baseService.getLeafDeptUserIds(idList);

        if(!CollectionUtils.isEmpty(checkUserIds))
        {
            //删除部门，需要校验部门下所有的用户是否在演练，与预案中，1.正在进行的演练，和尚未启动的演练里面已设置人员,2.方案里面已设置人员，
            String checkResult=null;
            //校验演练
            checkResult=pcDrillService.checkDrillExistUsers(new HashSet<>(checkUserIds));
            if(StringUtils.hasText(checkResult))
            {
                return Result.failed("该部门有用户已被设置为演练的人员，请先移除或停止演练，才能删除");
            }
            //校验预案
            checkResult=pcPlanService.checkPlanExistUsers(new HashSet<>(checkUserIds));
            if(StringUtils.hasText(checkResult))
            {
                return Result.failed("该部门有用户已被设置为预案的人员，请先移除或删除预案，才能删除");
            }
        }
        List<SystemDept> systemDepts=baseService.listByIds(idList);
        //校验是否存在关联的预案备案
        if(filingSystemDeptService.checkFilingRecord(systemDepts))
        {
            return Result.failed("选择的部门有设置预案备案，请先解除关联，才能删除");
        }

        //清除缓存
        baseService.deleteTreeCache();
        baseService.removeByIdList(idList);
        //删除预案备案部门
        filingSystemDeptService.removeFromSpd(systemDepts);
        return Result.ok();
    }



}
